/**
 * This file is part of maemo-examples package
 *  
 * This maemo code example is licensed under a MIT-style license,
 * that can be found in the file called "COPYING" in the same
 * directory as this file.
 * Copyright (c) 2007-2008 Nokia Corporation. All rights reserved.
 *
 * @author Shahzad Hussain Bangash
 * ext-shahzad.bangash@nokia.com
 * 
 */

#include "blues.hh"

BlueKlass::BlueKlass()
{
    memset(addr, 0, sizeof(addr));
    memset(name, 0, sizeof(name));
    memset(buff, 0, sizeof(buff));
    memset(incoming_Data, 0, sizeof(incoming_Data));
    max_rsp = 0;
    num_rsp = 0;
    dev_id = 0;
    sock = 0;
    len = 0;
    flags = 0;
    i = 0;
    counter = 0;
}

BlueKlass::~BlueKlass()
{
}

void BlueKlass::scan()
{
    inquiry_info* inquiry = NULL;
    dev_id = hci_get_route(NULL);
    sock = hci_open_dev( dev_id );
    if (dev_id < 0 || sock < 0) {
        perror("opening socket");
        exit(1);
    }

    len  = 8;
    max_rsp = 255;
    flags = IREQ_CACHE_FLUSH;
    inquiry = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
    
    num_rsp = hci_inquiry(dev_id,
                          len, 
                          max_rsp, 
                          NULL, 
                          &inquiry, 
                          flags);


    printf("Found Devices : %d  \n",num_rsp);

    printf("Resolving Names for Devices! \n");

    if( num_rsp < 0 ) 
        perror("hci_inquiry");

    for (i = 1; i <= num_rsp; ) {

        ba2str(&(inquiry+i)->bdaddr, addr);
        memset(name, 0, sizeof(name));

            if (hci_read_remote_name(sock,
                &(inquiry+i)->bdaddr, 
                sizeof(name),
                name, 
                0) < 0) {
                strcpy(name, "[unknown]");
            }
            printf("%i- %s  %s\n", i++, addr, name);
    }
    free( inquiry );
    close( sock );
}

int BlueKlass::listen_for_Connections()
{
    struct sockaddr_rc local_addr = {0};
    struct sockaddr_rc remote_addr = {0};
    
    opt = sizeof(remote_addr);

    sock = socket(AF_BLUETOOTH, 
                  SOCK_STREAM, 
                  BTPROTO_RFCOMM);
     
    if(sock < 0)
        printf("Error Creating Socket... \n");

     local_addr.rc_family = AF_BLUETOOTH; 
     local_addr.rc_bdaddr = *BDADDR_ANY; 
     local_addr.rc_channel = (uint8_t) 4;  //Channel 4
   
     client = bind(sock, 
                   (struct sockaddr *)&local_addr, 
                   sizeof(local_addr));
 
    if(client < 0)
        printf("Error binding \n");

    memset(name, 0, sizeof(name));
     

    printf("Waiting for incoming connections \n");
    printf("I can receive only 10 messages \n");
    
    listen(sock, 4);
     
    client = accept(sock, 
                    (struct sockaddr *)&remote_addr,
                    &opt);    

    ba2str( &remote_addr.rc_bdaddr, name);
     
    printf("Connection accepted from %s \n",name);


    while(counter < 10) {
        bytes_read =  recv(client, 
                           incoming_Data, 
                           sizeof(incoming_Data),
                           0);

        if(bytes_read < 0) {
            printf("Nothing received \n");
            return -1;
        }
        printf("Data Received : %s \n", incoming_Data);
     
        counter++;
    }
    close(sock);
    return 0;
}

bool BlueKlass::connect_Remote(int argc, char* argv[])
{
    struct sockaddr_rc local_addr = {0};
    struct sockaddr_rc remote_addr = {0};

    if(argc!= 2) {
        printf("Error parsing commandline \n");
        printf("Usage %s bluetooth Address \n",argv[0]);
        return false;
    }

    sock = socket(AF_BLUETOOTH,
                  SOCK_STREAM, 
                  BTPROTO_RFCOMM); 

    printf("Connecting to %s \n", argv[1]);

    local_addr.rc_family = AF_BLUETOOTH; //bluetooth protocol
    str2ba(argv[1],&local_addr.rc_bdaddr);  //remote address to connect to 
    local_addr.rc_channel = (uint8_t) 4; //channel 4
   
    fflush(stdin); 
      
    printf("Connecting... \n");
    chk_Status = connect(sock,
                         (struct sockaddr*)&local_addr,
                         sizeof(local_addr));

    if(chk_Status < 0) {
        printf("Host not available or invalid input host address \n");
        close(sock);
        return -1;
        } else {
            printf("Connected \n");
        }
    
    while(true) {
        printf("\n"); 
        printf("Send Data : ");
        fflush(stdin);
        scanf("%s", buff);
        chk_Status = send(sock, buff, 6, 0);

        if(chk_Status < 0) {
            printf("Unable to send message to the server \n");
            close(sock);
            return -1;
        }
    }

    close(sock);
    close(chk_Status);
    return 0;
}
